namespace UBlockly.Scriptable
{
    using UBlockly.UI;
    
    public class RuntimeTreeNode
    {
        //叶子
        private RuntimeTreeNode[] leafNodes;
        private ILFunc nodeFunc;
        private uint leafCount;
        public uint LeafCount => leafCount;

        private RuntimeTreeNode(ILFunc func, uint leafCount)
        {
            nodeFunc = func;
            this.leafCount = leafCount;
            leafNodes = new RuntimeTreeNode[leafCount];
        }
        
        void InitLeaf(int index, RuntimeTreeNode leafTree)
        {
            leafNodes[index] = leafTree;
        }

        //递归初始化参数
        void InitParam()
        {
            if (leafCount > 0)
            {
                nodeFunc.SetParamCount((int)leafCount);
                for (int i = 0; i < leafCount; i++)
                {
                    leafNodes[i].InitParam();
                    nodeFunc.SetParam(i,leafNodes[i].nodeFunc);
                }
            }
        }

        public BlockILFunc GetTreeFunc()
        {
            return nodeFunc as BlockILFunc;
        }

        public RuntimeTreeNode GetTree(uint leafIndex)
        {
            return leafNodes[leafIndex];
        }
        
        //根node递归生成一个函数执行树
        public static RuntimeTreeNode NodeTree(Node root)
        {
            RuntimeTreeNode rootTree = new RuntimeTreeNode(root.Scriptable.GetFunc(), root.Scriptable.ParamCount);
            if (root.Scriptable.ParamCount != 0)
            {
                for (int i = 0; i < root.Scriptable.ParamCount; i++)
                {
                    rootTree.InitLeaf(i, NodeTree(root.Block.GetPackerObject().GetParamObject(i).GetCurrentParam()));
                }
            }
            rootTree.InitParam();
            return rootTree;
        }

        public static RuntimeTreeNode NodeTree(SerializeTreeNode serializeTree)
        {
//            RuntimeTreeNode rootTree = new RuntimeTreeNode(root.Scriptable.GetFunc(), root.Scriptable.ParamCount);
//            if (root.Scriptable.ParamCount != 0)
//            {
//                for (int i = 0; i < root.Scriptable.ParamCount; i++)
//                {
//                    rootTree.InitLeaf(i, NodeTree(root.Block.GetPackerObject().GetParamObject(i).GetCurrentParam()));
//                }
//            }
//            rootTree.InitParam();
//            return rootTree;
            return null;
        }
    }
}